<html>
<head><meta charset="utf-8"><title>Yielding in async · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Yielding.20in.20async.html">Yielding in async</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="215992539"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Yielding%20in%20async/near/215992539" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Brandon Falk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Yielding.20in.20async.html#215992539">(Nov 08 2020 at 06:39)</a>:</h4>
<p>Dumb question, is there a way to yield execution in async, without actually blocking on anything? Eg. to use in a realtime OS where you want to allow for a switch to a different task, but don't have a specific reason to. In this sort of way:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">struct</span> <span class="nc">Yielder</span><span class="p">(</span><span class="kt">bool</span><span class="p">);</span><span class="w"></span>

<span class="k">impl</span><span class="w"> </span><span class="n">Yielder</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">new</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="bp">Self</span><span class="p">(</span><span class="kc">false</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">impl</span><span class="w"> </span><span class="n">Future</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Yielder</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">type</span> <span class="nc">Output</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">();</span><span class="w"></span>

<span class="w">    </span><span class="k">fn</span> <span class="nf">poll</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span>: <span class="nc">Pin</span><span class="o">&lt;&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">Self</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">cx</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="n">Context</span><span class="o">&lt;'</span><span class="nb">_</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Poll</span><span class="o">&lt;</span><span class="bp">Self</span>::<span class="n">Output</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="o">!</span><span class="bp">self</span><span class="p">.</span><span class="mi">0</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="bp">self</span><span class="p">.</span><span class="mi">0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span><span class="w"></span>
<span class="w">            </span><span class="n">Poll</span>::<span class="n">Pending</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="n">Poll</span>::<span class="n">Ready</span><span class="p">(())</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Fullish example: <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=7e00103c4fa3d5bfaddfb0d78f433902">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=7e00103c4fa3d5bfaddfb0d78f433902</a></p>



<a name="216001303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Yielding%20in%20async/near/216001303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mikail Bagishov <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Yielding.20in.20async.html#216001303">(Nov 08 2020 at 10:52)</a>:</h4>
<p>I think this should Just Work if you add missing <code>cx.waker.wake_by_ref()</code> before returning Pending</p>



<a name="216002474"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Yielding%20in%20async/near/216002474" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Yielding.20in.20async.html#216002474">(Nov 08 2020 at 11:22)</a>:</h4>
<p>Such a future is contained in <code>futures-lite</code>.</p>



<a name="216002487"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Yielding%20in%20async/near/216002487" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Yielding.20in.20async.html#216002487">(Nov 08 2020 at 11:24)</a>:</h4>
<p><a href="https://docs.rs/futures-lite/1.11.2/futures_lite/future/fn.yield_now.html">https://docs.rs/futures-lite/1.11.2/futures_lite/future/fn.yield_now.html</a></p>



<a name="216003255"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Yielding%20in%20async/near/216003255" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Brandon Falk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Yielding.20in.20async.html#216003255">(Nov 08 2020 at 11:42)</a>:</h4>
<p>Sounds good. Yeah, in this case this does "work", I just didn't know if there was built-in support for it in some way or another.</p>



<a name="216003566"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Yielding%20in%20async/near/216003566" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Yielding.20in.20async.html#216003566">(Nov 08 2020 at 11:50)</a>:</h4>
<p>Waking before returning pending (to directly reschedule the future) must work, even if the yield case wasn't considered.</p>
<p>The reason for this is that waking could always be done from a different thread and as such might always happen before returning from poll but after deciding how to return. (And similar races.)</p>



<a name="216003647"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Yielding%20in%20async/near/216003647" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Philipp Korber <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Yielding.20in.20async.html#216003647">(Nov 08 2020 at 11:52)</a>:</h4>
<p>So the "proper" way is waking the current waker and returning Pending.</p>
<p>There is no build-in syntax sugar for this.</p>



<a name="216004949"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Yielding%20in%20async/near/216004949" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Brandon Falk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Yielding.20in.20async.html#216004949">(Nov 08 2020 at 12:21)</a>:</h4>
<p>For sure! Thanks for that. I haven't yet started playing with wakers (just working with busy-loop schedulers). Mainly trying to get comfortable with the costs and performance of async. Trying to figure out if I want to convert one of my RTOSes to use it. Although, I don't really have much blocking I/O, it still might be somewhat useful for periodic things (like status messages). Kinda neat, but definitely starting to only now dip my toes in!</p>



<a name="216006020"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Yielding%20in%20async/near/216006020" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Zoxc <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Yielding.20in.20async.html#216006020">(Nov 08 2020 at 12:50)</a>:</h4>
<p>You'll want to inform your scheduler about the yield, otherwise your task might never execute again since there would be no events to schedule it.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>